﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.VisualBasic;
using Microsoft.CSharp;

namespace Qetza.TeamFoundation.WorkItemQuery.Admin
{
    /// <summary>
    /// Command to list the work item queries.
    /// </summary>
    public class CommandListWiq : ICommand
    {
        #region Fields

        /// <summary>
        /// The full path argument name.
        /// </summary>
        public static readonly string FullPathArgumentName;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes the <see cref="CommandListWiq"/> class.
        /// </summary>
        static CommandListWiq()
        {
            FullPathArgumentName = "/fullpath";
        }

        #endregion

        #region ICommand Members

        /// <inheritdoc />
        public string Name
        {
            get { return "list"; }
        }

        /// <inheritdoc />
        public string HelpText
        {
            get { return ResourceStrings.ListWiqHelpText; }
        }

        /// <inheritdoc />
        public IEnumerable<ParameterInfo> AllowedParameters
        {
            get
            {
                return new[] {
                    new ParameterInfo() { 
                        Name = CoreArgumentNames.Collection, 
                        ArgumentName = ResourceStrings.ProjectCollectionArgument, 
                        IsRequired = true, 
                        HelpText = ResourceStrings.ProjectCollectionHelpText
                        },
                    new ParameterInfo() { 
                        Name = CoreArgumentNames.Project, 
                        ArgumentName = ResourceStrings.ProjectArgument, 
                        IsRequired = true, 
                        HelpText = ResourceStrings.ProjectHelpText
                        }, 
                    new ParameterInfo() {
                        Name = CoreArgumentNames.Folder,
                        ArgumentName = ResourceStrings.FolderArgument,
                        HelpText = ResourceStrings.List_FolderHelpText
                        },
                    new ParameterInfo() {
                        Name = CoreArgumentNames.Recursive,
                        IsFlag = true,
                        HelpText = ResourceStrings.RecursiveHelpText
                        },
                    new ParameterInfo() {
                        Name = CoreArgumentNames.NoPath,
                        IsFlag = true,
                        IncompatibleArguments = new [] { CommandListWiq.FullPathArgumentName },
                        HelpText = ResourceStrings.NoPathHelpText
                        },
                    new ParameterInfo() {
                        Name = CommandListWiq.FullPathArgumentName,
                        IsFlag = true,
                        HelpText = ResourceStrings.FullPathHelpText
                        }
                    };
            }
        }

        /// <inheritdoc />
        public void Execute(IDictionary<string, string> parameters)
        {
            // get query hierarchy
            var hierarchySource = TfsUtility
                .GetWorkItemStore(parameters[CoreArgumentNames.Collection], parameters.ContainsKey(CoreArgumentNames.NoPrompt))
                .Projects[parameters[CoreArgumentNames.Project]]
                .QueryHierarchy;

            var root = (QueryFolder)hierarchySource;
            var parentPath = string.Empty;

            // get root folder if specified
            if (parameters.ContainsKey(CoreArgumentNames.Folder))
            {
                var item = hierarchySource.Find(parameters[CoreArgumentNames.Folder]);
                if (item == null)
                {
                    throw new Exception(string.Format(ResourceStrings.ErrorUnknownFolder, parameters[CoreArgumentNames.Folder]));
                }

                if (!(item is QueryFolder))
                {
                    throw new Exception(string.Format(ResourceStrings.ErrorNotAFolder, parameters[CoreArgumentNames.Folder]));
                }

                root = (QueryFolder)item;

                // display full path
                if (parameters.ContainsKey(CommandListWiq.FullPathArgumentName))
                {
                    parentPath = parameters[CoreArgumentNames.Folder] + "/";
                }
            }
     
            // list queries
            this.DisplayFolderQueries(
                root, 
                parentPath, 
                parameters.ContainsKey(CoreArgumentNames.Recursive),
                parameters.ContainsKey(CoreArgumentNames.NoPath)
                );
        }

        /// <inheritdoc />
        public void ValidateParameters(IDictionary<string, string> parameters)
        {
            return;
        }

        #endregion

        #region Private Helpers

        // Displays the work item queries in the specified folders.
        private void DisplayFolderQueries(QueryFolder folder, string parentPath, bool isRecursive, bool noPath)
        {
    
            foreach (var item in folder)
            {
                if (item is QueryDefinition)
                {
                    // display query
                    Console.WriteLine((noPath ? string.Empty : parentPath) + item.Name);
                }
                else if (isRecursive)
                {
                    // display subfolder queries
                    this.DisplayFolderQueries((QueryFolder)item, parentPath + item.Name + "/", isRecursive, noPath);
                }
            }
        }

        #endregion
    }
}
